package com.irdstudio.efp.esb.api.common;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;

import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.basic.framework.core.validate.SimpleJSR303Validator;

@Aspect
@Component
public class ValidateAspect {

	private static Logger logger = LoggerFactory.getLogger(ValidateAspect.class);

	@Around("execution(* com.irdstudio.efp.esb.api.rest..*.*(..,org.springframework.validation.BindingResult,..,java.lang.Exception))")
	public Object validateControllerMethod(ProceedingJoinPoint jp) throws Throwable {
		List<String> errorMessages = new LinkedList<String>();
		Stream.of(jp.getArgs()).filter(BindingResult.class::isInstance).map(BindingResult.class::cast).filter(BindingResult::hasErrors)
				.map(BindingResult::getFieldErrors)
				.flatMap(errors -> errors.stream().filter(Objects::nonNull).map(i -> new StringBuilder("字段：").append(i.getField())
						.append(" -- "+i.getDefaultMessage()).append(", 当前值：").append(i.getRejectedValue()).toString()))
				.forEach(errorMessages::add);
		int argsSize = jp.getArgs().length;
		if (errorMessages.isEmpty()) {
			jp.getArgs()[argsSize - 1] = null;
		} else {
			String errMsg = errorMessages.toString();
			jp.getArgs()[argsSize - 1] = new Exception(errMsg);
			logger.error(errMsg);
		}
		// 处理之后
		Object obj = jp.proceed(jp.getArgs());
		try {
			if (obj instanceof EsbRespServiceBean) {
				SimpleJSR303Validator.validateAndThrow(obj);
			}
		} catch (Exception e) {
			logger.error("校验ESB返回对象失败信息为：" + e.getMessage());
		}
		return obj;
	}

}
